using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Forest.Cat.Domain.Entities;
using Forest.Core;
using Forest.Core.Caching;
using Forest.Core.Data;
using Forest.Core.Events;

namespace Forest.Cat.Domain.Services.Catalog
{
    public partial class CatalogItemService:ICatalogItemService
    {
        #region Constants
        private const string CATALOGITEM_BY_ID_KEY = "catalogitem.id-{0}";
        private const string CATALOGITEM_PATTERN_KEY = "catalogitem.";
        #endregion

        #region Fields
        private readonly IRepository<CatalogItem> _catalogitemRepository;
		private readonly ICacheManager _cacheManager;
        private readonly IEventPublisher _eventPublisher;
        #endregion

        #region Ctor
        public CatalogItemService(IRepository<CatalogItem> catalogitemRepository, ICacheManager cacheManager, IEventPublisher eventPublisher)
        {
            _catalogitemRepository = catalogitemRepository;
			_cacheManager = cacheManager;
            _eventPublisher = eventPublisher;
        }
        #endregion

        #region Base Methods
        public virtual void DeleteCatalogItem(CatalogItem catalogitem)
        {
            if (catalogitem == null)
                throw new ArgumentNullException("CatalogItem");

            _catalogitemRepository.Delete(catalogitem);
			_cacheManager.RemoveByPattern(CATALOGITEM_PATTERN_KEY);
			_eventPublisher.EntityDeleted(catalogitem);
        }

        public CatalogItem GetCatalogItemById(Guid catalogitemId)
        {
            if (catalogitemId == Guid.Empty)
                return null;
            string key = string.Format(CATALOGITEM_BY_ID_KEY, catalogitemId);

            return _cacheManager.Get(key, () => {
                var cl = _catalogitemRepository.GetById(catalogitemId);
                return cl;
            });
        }

        public virtual IPagedList<CatalogItem> GetAllCatalogItems(int pageIndex, int pageSize)
        {
            var query = _catalogitemRepository.Table;
            query = query.OrderBy(w => w.Id);
            var items = new PagedList<CatalogItem>(query, pageIndex, pageSize);
            return items;
        }

        public virtual void InsertCatalogItem(CatalogItem catalogitem)
        {
            if (catalogitem == null)
                throw new ArgumentNullException("CatalogItem");
            _catalogitemRepository.Insert(catalogitem);
			_cacheManager.RemoveByPattern(CATALOGITEM_PATTERN_KEY);
			_eventPublisher.EntityInserted(catalogitem);
        }

        public virtual void UpdateCatalogItem(CatalogItem catalogitem)
        {
            if (catalogitem == null)
                throw new ArgumentNullException("CatalogItem");
            _catalogitemRepository.Update(catalogitem);
			_cacheManager.RemoveByPattern(CATALOGITEM_PATTERN_KEY);
			_eventPublisher.EntityUpdated(catalogitem);
        }
        #endregion

        #region Extend Methods
        public IQueryable<CatalogItem> GetCatalogItemList(Guid parentid, bool hasParentId = false, bool isPosted = true)
        {
            var listhasParentId = _catalogitemRepository.Table.Where(i => i.Posted == isPosted && (parentid==Guid.Empty || i.ParentId == parentid)).OrderBy(i=>i.SortOrder);

            var listnoPartentId = _catalogitemRepository.Table.Where(i => i.Posted == isPosted && i.ParentId == null && (parentid == Guid.Empty || i.ParentId == parentid)).OrderBy(i => i.SortOrder);

            var list = hasParentId == true ? listhasParentId : listnoPartentId;

            return list;
        }


        #endregion



    }
}
